package cn.tnar.parkservice.service.impl;


import cn.tnar.parkservice.config.ParkConstant;
import cn.tnar.parkservice.exception.CouponsException;
import cn.tnar.parkservice.model.request.ParkingInfo;
import cn.tnar.parkservice.model.request.RegRequest;
import cn.tnar.parkservice.service.CouponsService;
import cn.tnar.parkservice.util.HttpUtil;
import cn.tnar.parkservice.util.KesbCommonParam;
import cn.tnar.pms.kesb.KesbClient;
import cn.tnar.pms.kesb.KesbException;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author xzhang
 * @date 2019/9/6
 */
@Slf4j
@Service
public class CouponsServiceImpl implements CouponsService {
    @Autowired
    KesbClient kesbClient;

    @Value("${tnar.couponsServerUrl}")
    private String couponsServerUrl;

    @Value("${tnar.mq.routingKey}")
    private String routingKey = "coupon";

    private static final String MOBILE_FLY = "mobilefly";

    private String getCouponPrefix = "/provide/automatic/couponRequest";


    @Autowired
    private RabbitTemplate rabbitTemplate;


    private Function<String, String> carPlateColor2CarType = carPlateColor -> {
        switch (carPlateColor) {
            case "黄":
                return "3";
            case "绿":
                return "6";
            case "白":
                return "7";
            case "蓝":
            default:
                return "1";
        }
    };

    @Override
    public Map<String, String> registerTnarMember(RegRequest regRequest) throws CouponsException {
        try {
            Map<String, String> params = new HashMap<String, String>();
            params.put("wxno", regRequest.getOpenId());
            params.put("mobileno", regRequest.getMobileNo());
            params.put("datavalid", regRequest.getDataValid());
            params.put("datas", regRequest.getCode());
            params.put("checktoken", regRequest.getCheckToken());
            return kesbClient.request(ParkConstant.API_USER_REGISTRY, KesbCommonParam.commonRequstParam(params, ParkConstant.API_USER_REGISTRY, "0", regRequest.getCustSession()));
        } catch (KesbException e) {
            throw new CouponsException(e.getCode(), e.getMessage());
        } catch (IOException e) {
            throw new CouponsException("-1", "注册用户异常，请稍后重试", e);
        }
    }

    @Override
    public Map<String, String> getMobileCode(String mobile) throws CouponsException {
        try {
            Map<String, String> params = new HashMap<String, String>();
            params.put("mobile", mobile);
            final Map<String, String> request = kesbClient.request(ParkConstant.API_GET_MOBILE_KEY, params);
            params.put("mobileno", mobile);
            final String session = request.get("session");
            String key = String.format("%s%s%s", mobile, session, MOBILE_FLY);
            params.put("key", DigestUtils.md5Hex(key));
            return kesbClient.request(ParkConstant.API_GET_MOBILE_CODE, KesbCommonParam.commonRequstParam(params, ParkConstant.API_GET_MOBILE_CODE, "", ""));
        } catch (KesbException e) {
            throw new CouponsException(e.getCode(), e.getMessage());
        } catch (IOException e) {
            throw new CouponsException("-1", "获取验证码异常，请稍后重试", e);
        }
    }

    @Override
    public void bindCarPlateNo(String custId, String carPlateNo, String carType, String session) throws CouponsException {
        try {
            Map<String, String> params = new HashMap<String, String>();
            params.put("cust_id", custId);
            params.put("car_id", carPlateNo);
            if (StringUtils.isNotEmpty(carType)) {
                params.put("car_type", carType);
            } else {
                params.put("car_type", "1");
            }
            kesbClient.request(ParkConstant.API_BIND_CAR_PLATE_NO, KesbCommonParam.commonRequstParam(params, ParkConstant.API_BIND_CAR_PLATE_NO, custId, session));
        } catch (KesbException e) {
            throw new CouponsException(e.getCode(), e.getMessage());
        } catch (IOException e) {
            throw new CouponsException("-1", "绑定车牌异常，请稍后重试", e);
        }
    }

    @Override
    public List<ParkingInfo> queryParkingRecord(String custId, String carPlateNo, String carType) throws CouponsException {

        String carTypeStr = carType;

//        if (StringUtils.isEmpty(carType)) {
//            carTypeStr = "1";
//        }
        List<ParkingInfo> result = new ArrayList<>();
        if (StringUtils.isNotEmpty(carPlateNo)) {
            final List<ParkingInfo> parkingInfoAndCalcFee = getParkingInfoAndCalcFee(carPlateNo, carTypeStr);
            if (parkingInfoAndCalcFee != null) {
                result.addAll(parkingInfoAndCalcFee);
            }
        } else if (StringUtils.isNotEmpty(custId)) {
            Map<String, String> params = new HashMap<String, String>();
            params.put("query_type", "1");
            params.put("cust_id", custId);
            try {
                Map<String, String> carinfos = kesbClient.request(ParkConstant.API_QUERY_BIND_CAR_INFO, params);
                if (carinfos != null) {
                    log.info("用户{}车牌绑定信息{}", custId, carinfos);
                    final String[] car_ids = carinfos.get("car_ids").split("_");
                    final String[] car_types = carinfos.get("car_types").split("_");
                    int idlen = car_ids.length;
                    int i = 0;
                    for (; i < idlen; i++) {
                        final List<ParkingInfo> parkingInfoAndCalcFee = getParkingInfoAndCalcFee(car_ids[i], car_types[i]);
                        if (parkingInfoAndCalcFee != null) {
                            result.addAll(parkingInfoAndCalcFee);
                        }
                    }
                }
            } catch (KesbException e) {
                throw new CouponsException(e.getCode(), e.getMessage());
            } catch (IOException e) {
                throw new CouponsException("-1", "停车记录信息查询异常，请稍后重试", e);
            }
        }
        log.info("====》停车记录信息{}", result);
        return result;

    }

    @Override
    public void pushCouponsInfo(String carPlateNo, String parkCode, String carType) throws CouponsException {
        try {
            Map<String, String> req = new HashMap<>();
            req.put("carNo", carPlateNo);
            req.put("carType", carType);
            req.put("parkNo", parkCode);
            log.info("开始请求优惠券信息-车牌号{}|车辆类型{}|停车场编号{}", carPlateNo, carType, parkCode);
            String couponsResp = HttpUtil.postJsonWithResponse(couponsServerUrl + getCouponPrefix, JSON.toJSONString(req));
            log.info("获取的优惠券信息-{}", couponsResp);
            Map<String, Object> map = JSON.parseObject(couponsResp, Map.class);
            if (Integer.parseInt(map.get("code").toString()) == 0) {
                log.info("发消息{}-{}", routingKey + "." + parkCode, map);
                map.put("carPlateNo", carPlateNo);
                map.put("carType", carType);
                rabbitTemplate.convertAndSend("amq.topic", routingKey + "." + parkCode, JSON.toJSONString(map));
            } else {
                log.error("没有获取到优惠券信息{}", couponsResp);
                throw new CouponsException("-1", "获取优惠券异常");
            }
        } catch (Exception e) {
            throw new CouponsException("-1", "获取优惠券异常", e);
        }
    }

    @Override
    public ParkingInfo calcFee(ParkingInfo parkingInfo) throws CouponsException {
        try {
            Map<String, String> feeparams = new HashMap<String, String>();
            feeparams.put("park_code", parkingInfo.getPark_code());
            feeparams.put("region_code", parkingInfo.getRegion_code());
            feeparams.put("intime", parkingInfo.getIntime());
            feeparams.put("car_id", parkingInfo.getCar_id());
            feeparams.put("cartype", parkingInfo.getCartype());
            Map<String, String> fee = kesbClient.request(ParkConstant.API_CALC_FEE, feeparams);
            log.info("计费信息{}", fee);
            parkingInfo.setParkamt(fee.get("parkamt"));
            parkingInfo.setParktime(fee.get("park_time"));
            parkingInfo.setPaidamt(fee.get("paidamt"));
            return parkingInfo;
        } catch (Exception e) {
            log.error("cale fee error", e);
            throw new CouponsException("-1", "计算费用异常", e);

        }
    }

    private List<ParkingInfo> getParkingInfoAndCalcFee(String carPlateNo, String carType) {
        try {
            Map<String, String> params = new HashMap<String, String>();
            params.put("car_id", carPlateNo);
            if (StringUtils.isNotBlank(carType)) {
                params.put("carType", carType);
            }
            List<Map<String, String>> listMap = kesbClient.requestList(ParkConstant.API_QUERY_PARKING, params);
            log.info("停车信息{}", listMap);
            List<ParkingInfo> list = listMap
                    .parallelStream().filter(x -> !x.isEmpty() && x.size() > 0)
                    .map(x -> {
                        ParkingInfo parkingInfo = new ParkingInfo();
                        parkingInfo.setParkname(x.get("parkname"));
                        parkingInfo.setPark_code(x.get("park_code"));
                        parkingInfo.setRegion_code(x.get("region_code"));
                        parkingInfo.setInphoto(x.get("inphoto"));
                        parkingInfo.setInsmallphoto(x.get("insmallphoto"));
                        parkingInfo.setIntime(x.get("intime"));
                        parkingInfo.setParktime(x.get("parktime"));
                        parkingInfo.setCar_id(x.get("car_id"));
                        parkingInfo.setCartype(x.get("cartype"));
                        parkingInfo.setParkamt(x.get("parkamt"));
                        parkingInfo.setPaidamt(x.get("paidAmt"));
                        return parkingInfo;
                    }).collect(Collectors.toList());
            return list;
        } catch (Exception e) {
            log.error("getParkingInfoAndCalcFee error", e);
            return null;
        }
    }
}
